package com.blindBox.front.handler.mailHandler;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.blindBox.front.commonResult.MsgBackToFront;
import com.blindBox.front.dao_pojo.User;
import com.blindBox.front.handler.tokenHandler.TokenHandler;
import com.blindBox.front.service.UserService;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Component;

import java.util.Random;
import java.util.concurrent.TimeUnit;

@Component
public class MailHandler
{
    @Value("${spring.mail.username}")
    private String from;//谁发送邮件
    //发送的标题
    private final String mail_title="盲盒祝您玩的愉快!";
    //找回密码发送的内容
    private final String mail_content="亲爱的用户，您当前账号的密码为: ";
    //邮箱登录
    private final String code_login_content="亲爱的用户，您的登录验证码为: ";
    //邮箱注册
    private final String code_register_by_eamil="亲爱的用户，你的注册验证码为: ";
    //检验qq邮箱格式
    private final String qq_format="[1-9]([0-9]{4,10})@qq.com";
    @Autowired
    private JavaMailSender mailSender;
    @Autowired
    private UserService userService;
    @Autowired
    private TokenHandler tokenHandler;
    @Autowired
    private RedisTemplate redisTemplate;
    @Value("${user.eamil_code_expire_time}")
    private long eamil_code_expire_time;

    //发送邮件,找回用户密码
    public synchronized MsgBackToFront findUserPwd(String u_name)
    {
        //查找出当前用户的邮箱号码
        User user = userService.getOne(new QueryWrapper<User>().eq("uname", u_name));
        if(user==null)
        {
            //用户名输入有误，当前用户不存在
            return new MsgBackToFront(null,MsgBackToFront.NO_USER);
        }
        String u_mail = user.getMail();
         //检验邮箱格式是否合法
        if(!u_mail.matches(qq_format))
            return new MsgBackToFront(null,MsgBackToFront.MAIL_FORMAT_ERROR);
        //通过邮箱发送密码给指定用户
        doSendSimpleMail(u_mail,user.getUpwd());
        return new MsgBackToFront(null,MsgBackToFront.HANDLE_SUCCESS);
    }

    //通过邮箱，发送验证码给指定用户
    public synchronized void sendCodeToUser(String eamil,String code)
    {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(from);
        message.setTo(eamil);
        message.setSubject(mail_title);
        message.setText(code_login_content+code);
        mailSender.send(message);
    }

    //发送给谁,标题,内容
    private synchronized void doSendSimpleMail(String to,String pwd){
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(from);
        message.setTo(to);
        message.setSubject(mail_title);
        message.setText(mail_content+pwd);
        mailSender.send(message);
    }

    //发送验证码
    public MsgBackToFront sendCode(String email)
    {
        try
        {
            //判断邮箱是否填写正确
            User user = userService.getOne(new QueryWrapper<User>().eq("mail", email));
            //邮箱填写错误
            if(user==null)
            {
                //邮箱填写错误
                return  new MsgBackToFront(null,MsgBackToFront.MAIL_ERROR);
            }
            //生成随机验证码
            String codeRandom = createCodeRandom();

            System.out.println("++++++++++++++++++++++++++++");
            System.out.println("生成随机验证码为:  "+codeRandom);
            System.out.println("++++++++++++++++++++++++++++");

            //发送验证码
            this.sendCodeToUser(email,codeRandom);
            //设置当前登录用户的验证码过期时间
            redisTemplate.boundValueOps(email).set(codeRandom,eamil_code_expire_time, TimeUnit.MINUTES);
            //处理成功，返回结果
            return new MsgBackToFront(codeRandom,MsgBackToFront.HANDLE_SUCCESS);
        }
        catch (Exception e)
        {
            System.out.println("邮箱发送出现异常!!!!");
        }
        return new MsgBackToFront(null,MsgBackToFront.EXCEPTION_ERROR);
    }

    //检验邮箱的登录
    public MsgBackToFront verify_eamil_login(String email,String code)
    {
        //既然发送了验证码，说明邮箱格式正确，且不存在问题
        User user = userService.getOne(new QueryWrapper<User>().eq("mail", email));
        //判断用户是否被封号了
        if(user.getFlag()==1)
        {
            return new MsgBackToFront(null,MsgBackToFront.USER_NO_RIGHT);
        }
        //判断指定key是否过期
        if(!hasKey(email))
        {
            //验证码过期
            return new MsgBackToFront(null,MsgBackToFront.CODE_EXPIRED);
        }
        //检验验证码是否输入正确
        String right_code = getKey(email);

        System.out.println("=========================");
        System.out.println("当前用户输入的验证码为:  "+code);
        System.out.println("发送的验证码为:  "+right_code);
        System.out.println("===========================");

        //检验和用户输入的验证码是否一致
        if(right_code.equals(code))
        {
            //返回给前端token和用户名
            try {

                String token = tokenHandler.encryptionUnameAndUpwd(user);
                String[] ret={token,user.getUname()};
                return new MsgBackToFront(ret,MsgBackToFront.HANDLE_SUCCESS);

            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            return new MsgBackToFront(null,MsgBackToFront.EXCEPTION_ERROR);
        }
        //输入的验证码有误
        return new MsgBackToFront(null,MsgBackToFront.CODE_ERROR);
    }

    //指定key的失效时间
    public void expire(String key)
    {
        //失效时间
        redisTemplate.expire(key,eamil_code_expire_time, TimeUnit.MINUTES);
    }

    //    判断key是否存在
    //存在返回true,不存在返回false
    public boolean hasKey(String key){
        return redisTemplate.hasKey(key);
    }

    //获取指定key的值
    public String getKey(String key)
    {
        return (String) redisTemplate.boundValueOps(key).get();
    }

    //生成随机的验证码
    public String createCodeRandom()
    {
        String code="";//保存生成的验证码
        long  t = System.currentTimeMillis(); //获得当前时间的毫秒数
        Random rd =  new  Random(t); //作为种子数传入到Random的构造器中
        //六位数字的验证码
        for(int i=0;i<6;i++)
        {
            //验证码每个数字的范围是0-9
            int ret = rd.nextInt(9) + 1;
            code+=ret;
        }
        return code;
    }

    public MsgBackToFront register_sendCode(String email)
    {
 try{
        //检查邮箱的格式
        //检验邮箱格式是否合法
        if(!email.matches(qq_format))
            return new MsgBackToFront(null,MsgBackToFront.MAIL_FORMAT_ERROR);

        //生成随机验证码
        String codeRandom = createCodeRandom();

        System.out.println("++++++++++++++++++++++++++++");
        System.out.println("生成随机验证码为:  "+codeRandom);
        System.out.println("++++++++++++++++++++++++++++");

        //发送验证码
        this.sendCodeToUser(email,codeRandom);
        //设置当前登录用户的验证码过期时间
        redisTemplate.boundValueOps("r_"+email).set(codeRandom,eamil_code_expire_time, TimeUnit.MINUTES);
        //处理成功，返回结果
        return new MsgBackToFront(codeRandom,MsgBackToFront.HANDLE_SUCCESS);
 }
 catch (Exception e)
 {
     System.out.println("邮箱发送出现异常!!!!");
 }
        return new MsgBackToFront(null,MsgBackToFront.EXCEPTION_ERROR);
    }

    public MsgBackToFront register_verify_eamil_login(User user,String email, String code) {

        //判断指定key是否过期
        if(!hasKey("r_"+email))
        {
            //验证码过期
            return new MsgBackToFront(null,MsgBackToFront.CODE_EXPIRED);
        }
        //检验验证码是否输入正确
        String right_code = getKey("r_"+email);

        System.out.println("=========================");
        System.out.println("当前用户输入的验证码为:  "+code);
        System.out.println("发送的验证码为:  "+right_code);
        System.out.println("===========================");

        //检验和用户输入的验证码是否一致
        if(right_code.equals(code))
        {
            //返回给前端token和用户名
            try {
                String token = tokenHandler.encryptionUnameAndUpwd(user);
                String[] ret={token,user.getUname()};
                return new MsgBackToFront(ret,MsgBackToFront.HANDLE_SUCCESS);

            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            return new MsgBackToFront(null,MsgBackToFront.EXCEPTION_ERROR);
        }
        //输入的验证码有误
        return new MsgBackToFront(null,MsgBackToFront.CODE_ERROR);
    }
}
